#ifndef VISUALIZER_H
#define VISUALIZER_H

/// opengl
#include <GL/glew.h>
#ifdef MACOS
#include <glut.h>
#else
#include <GL/glut.h>
#endif

/// vcg
#include <vcg/simplex/vertex/base.h>
#include <vcg/simplex/face/base.h>
#include <vcg/complex/trimesh/base.h>
#include <vcg/complex/trimesh/update/bounding.h>
#include <vcg/complex/trimesh/update/normal.h>
#include <vcg/complex/trimesh/create/platonic.h>
#include <vcg/space/color4.h>

/// wrapper
#include <wrap/io_trimesh/import.h>
#include <wrap/gl/trimesh.h>
#include <wrap/gui/trackball.h>

/// vcg picking
#include <wrap/gl/pick.h>
#include <wrap/gl/picking.h>
#include <vcg/space/index/grid_static_ptr.h>
#include <vcg/complex/trimesh/closest.h>
#include <vcg/complex/trimesh/append.h>
#include <vcg/complex/trimesh/inertia.h>

/// app
#include "expand.h"
#include "mymesh.h"
#include "lights.h"
#include "../../myProject/AG/Cluster.h"

class Visualizer
{
 public:
    typedef CMesh::FaceType FaceType;
    typedef CMesh::FacePointer FacePointer;
    typedef CMesh::FaceIterator FaceIterator;
    typedef CMesh::VertexIterator VertexIterator;
    typedef CMesh::VertContainer VertContainer;
    typedef CMesh::VertexType VertexType;
    typedef CMesh::VertexPointer VertexPointer;
    typedef CMesh::VertexPointer VertexTypeP;
    typedef vcg::face::VFIterator<FaceType> VFIteratorType;
    typedef CMesh::CoordType CoordType;
    typedef CoordType::ScalarType ScalarType;

public:
    Visualizer (int w, int h);
    void loadMesh(char *meshfile);
    void initializeGL ();
    void resizeGL (int w, int h);
    void paintGL ();
    void selectGL (int mX, int mY);
    void mousePress (int x, int y, vcg::Trackball::Button b);
    void mouseMove (int x, int y);
    void mouseRelease (int x, int y, vcg::Trackball::Button b);
    void mouseWheel (int d, vcg::Trackball::Button b);
    void launchSphereBreadthQuery ();
    void launchSphereSpaceQuery ();
    void launchSphereStructureQuery();
    void setSphereRadius (float sr);

private:
    void updateGL ();
    void initMesh ();
    void setLightModel ();
    double getAverageEdge();
    void clearSpaceV ();
    void clearTopoV ();
    void clearStructureV();

public:
    bool meshEnabled;
    bool fancyLight;
#define DRAW_MODE_NUM 6
    typedef enum {SMOOTH, POINTS, WIRE, FLATWIRE, HIDDEN, FLAT} DrawMode;
    DrawMode drawMode;
    bool enableSphereBreadthV;
    bool enableSphereSpaceV;
    bool enableSphereStructureV;
    bool enablePickV;
    float scaledSphereRadius;
    float averageEdge;
    float sphereRadius;

private:
    CMesh mesh;
    vcg::GlTrimesh<CMesh> wrap;
    vcg::Trackball track;
    GLLightSetting ls;
    int width;
    int height;
    CMesh::PerVertexAttributeHandle<bool> sphereSpaceV;
    CMesh::PerVertexAttributeHandle<bool> sphereBreadthV;
    CMesh::PerVertexAttributeHandle<bool> sphereStructureV;
    CVertex* pick;
    Expander nav;
    //friend class SpatialIndex;
};

#endif // VISUALIZER_H
